package com.pig4cloud.pig.village.rules;

import com.pig4cloud.pig.village.rules.generator.RuleConditionTypeMapping;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

public class RuleCondition {

	private String conditionKey;
	private String conditionValue;
	private RuleConditionType valueType;

	public RuleCondition(String conditionKey, String conditionValue) {
		this.conditionKey = conditionKey;
		this.conditionValue = conditionValue;
	}

	public String getConditionKey() {
		return conditionKey;
	}

	public void setConditionKey(String conditionKey) {
		this.conditionKey = conditionKey;
	}

	public String getConditionValue() {
		return conditionValue;
	}

	public void setConditionValue(String conditionValue) {
		this.conditionValue = conditionValue;
	}

	public RuleConditionType getValueType() {
		return returnValueType();
	}

	private RuleConditionType returnValueType() {
		if (StringUtils.isEmpty(conditionValue)) {
			return null;
		}

		List<RuleConditionType> possibleConditionTypes = RuleConditionTypeMapping.getValue().get(conditionKey);
		if (possibleConditionTypes == null) {
			return guessValueType(possibleConditionTypes);
		}

		// Return only one type.
		if (possibleConditionTypes.size() == 1) {
			return possibleConditionTypes.get(0);
		}
		// If you cannot determine which condition type, try the following methods
		return guessValueType(possibleConditionTypes);
	}

	private RuleConditionType guessValueType(List<RuleConditionType> possibleConditionTypes) {
		if (conditionValue.contains(",") && possibleConditionTypes.contains(RuleConditionType.ARRAY)) {
			return RuleConditionType.ARRAY;
		} else if (isComparatorExp(conditionValue)) {
			return RuleConditionType.NUMERIC_RANGE;
		} else if (StringUtils.isNumeric(conditionValue)) {
			return RuleConditionType.NUMERIC_SINGLE;
		} else if (isBooleanExp(conditionValue)) {
			return RuleConditionType.BOOLEAN;
		} else {
			return RuleConditionType.STRING;
		}
	}

	private boolean isComparatorExp(String input) {
		return input.contains("<") || input.contains(">") || input.contains("<=") || input.contains(">=");
	}

	private boolean isBooleanExp(String input) {
		return "true".equalsIgnoreCase(input) || "false".equalsIgnoreCase(input);
	}
}

